Imports System.Collections.ObjectModel
Imports System.ComponentModel

Namespace Collections

    ''' <summary>
    ''' Supports a simple iteration over a collection of XElements.
    ''' </summary>
    ''' <typeparam name="TType">The type of objects to enumerate.</typeparam>
    Public NotInheritable Class XElementCollectionEnumerator(Of TType As XElement)
        Implements IEnumerator(Of TType)

        Private __elements As Object()
        Private __current As Integer = -1

        ''' <summary>Initializes an instance of the <see cref="XElementCollectionEnumerator" /> class.</summary>
        ''' <param name="elements">An <see cref="Array"/> that contains the elements to iterate through.</param>
        Friend Sub New(ByVal elements As Object())
            __elements = elements
        End Sub

        ''' <summary>Gets the element in the collection at the current position of the enumerator.</summary>
        ''' <value>The element in the collection at the current position of the enumerator.</value>
        ''' <exception cref="InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element.</exception>
        Public ReadOnly Property Current() As TType Implements System.Collections.Generic.IEnumerator(Of TType).Current
            Get
                If (__current < 0) Then
                    Throw New InvalidOperationException("The enumerator is positioned before the first element of the collection or after the last element.")
                End If
                Return DirectCast(__elements(__current), TType)
            End Get
        End Property

        ''' <summary>
        ''' Advances the enumerator to the next element of the collection.
        ''' </summary>
        ''' <returns><c>True</c> if the enumerator was successfully advanced to the next element; <c>False</c> if the enumerator has passed the end of the collection.</returns>
        Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
            __current += 1
            Return (__current < __elements.Length)
        End Function

        ''' <summary>
        ''' Sets the enumerator to its initial position, which is before the first element in the collection.
        ''' </summary>
        Public Sub Reset() Implements System.Collections.IEnumerator.Reset
            __current = -1
        End Sub

#Region " IEnumerator Implementation "

        <Browsable(False)> _
        <DebuggerBrowsable(DebuggerBrowsableState.Never)> _
        Private ReadOnly Property IEnumeratorCurrent() As Object Implements System.Collections.IEnumerator.Current
            Get
                Return __elements(__current)
            End Get
        End Property

#End Region

#Region " IDisposable Implementation "

        ' IDisposable
        Private __disposed As Boolean = False        ' To detect redundant calls
        Private Sub Dispose(ByVal disposing As Boolean)
            If Not Me.__disposed Then
                If disposing Then
                    ' TODO: free other state (managed objects).
                End If

                ' TODO: free your own state (unmanaged objects).
                ' TODO: set large fields to null.
            End If
            Me.__disposed = True
        End Sub

        ''' <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
        ''' <filterpriority>2</filterpriority>
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub

#End Region

    End Class
End Namespace
